<template>
  <div class="component-box">
    <div class="component-box-top">
      <div class="cb-top-search">
        <el-input
            placeholder="请输入查询内容……"
            suffix-icon="el-icon-search"
            size="mini"
        ></el-input>
      </div>

      <div class="cb-top-filter">
        <ul class="tabs">
          <li :class="{ 'active-li': active_li === 1 }" @click="changeTab(1)">
            内置
          </li>
          <li :class="{ 'active-li': active_li === 2 }" @click="changeTab(2)">
            我的
          </li>
          <li :class="{ 'active-li': active_li === 3 }" @click="changeTab(3)">
            团队
          </li>
          <li :class="{ 'active-li': active_li === 4 }" @click="changeTab(4)">
            发现
          </li>
        </ul>

        <div class="filter" v-if="active_li === 1">
          <template v-for="(item, index) in tagList">
            <el-tag
                size="mini"
                :key="item"
                :type="active_tag === index ? '' : 'info'"
                :effect="active_tag === index ? 'dark' : 'plain'"
                @click="selectedTag(index)"
            >
              {{ item }}
            </el-tag>
          </template>
        </div>
      </div>
    </div>

    <el-divider></el-divider>
    <div v-if="active_li === 1" class="bottom-content">
      <div class="component-box-con">
        <draggable-template :designer="designer"></draggable-template>
      </div>

      <el-divider></el-divider>

      <div class="component-box-foo">
        <level-tree :designer="designer"></level-tree>
      </div>
    </div>
    <div v-if="active_li === 2" class="componentList">
      <draggable
          tag="ul"
          :list="componentList"
          :group="{ name: 'dragGroup', pull: 'clone', put: false }"
          ghost-class="ghost"
          :clone="handleContainerWidgetClone"
          :move="checkMove"

      >
        <li
            v-for="(ft, idx) in componentList"
            :key="idx"
            class="field-widget-item"
            @dblclick="addFieldByDbClick(ft)"
        >
          <!-- <el-popover placement="right" trigger="hover">
              <img slot="reference" :src="ft.imgUrl" style="width: 200px">
              <img :src="ft.imgUrl" style="height: 600px;width: 720px">
            </el-popover> -->
          <div class="bottom clear-fix">
            <span class="ft-title">#{{ idx + 1 }} {{ ft.nameCn }} {{ft.code}}</span>
            <!-- <el-button
                type="text"
                class="right-button"
                @click="addFieldByDbClick(ft.json)"
            >
              加载组件</el-button
            > -->
            <div>
            <el-button type="text" icon="el-icon-delete" @click="del(ft)"></el-button>
            <el-button type="text" icon="el-icon-edit" @click="edit(ft)"></el-button>
            </div>
          </div>
        </li>
      </draggable>
    </div>
  </div>
</template>

<script>
import DraggableTemplate from "@/components/form-designer/widget-panel/draggable-template.vue";
import LevelTree from "@/components/form-designer/toolbar-panel/levelTree.vue";
import * as api from "@/api/applicationManage/applicationManage";
import {generateId} from "@/utils/util";

import WidgetProperties from "@/components/form-designer/setting-panel/propertyRegister";

const {EVENT_PROPERTIES} = WidgetProperties;

export default {
  name: "component-box",
  components: {LevelTree, DraggableTemplate},
  props: {
    designer: Object,
    editComponent: Function,
  },
  data() {
    return {
      active_li: 1,
      active_tag: 0,
      tagList: ["全部", "常用", "表单", "导航", "图表", "多媒体"],
      componentList: [], //组件--我的列表
    };
  },
  methods: {

    checkMove(evt) {
      return this.designer.checkWidgetMove(evt);
    },
    del(data) {
      api.componentDel({id: data.oid}).then(res=>{
        this.$message.success('删除成功！')
      })
    },
    edit(data) {
      this.editComponent(data);
    },
    handleContainerWidgetClone(origin) {
      return this.designer.copyNewContainerWidgetComp(JSON.parse(origin.json).widgetList)
    },
    checkContainerMove(evt) {
      return this.designer.checkWidgetMove(evt);
    },
    addFieldByDbClick(temp) {
      /*
            * 存在一个页面拖拽多个相同自定义组件
            * 下级组件id重新随机 ✅
            * 变量名称随机 ✅
            * 脚本名称随机 ✅
            * 数据源名称随机 ✅
            * */
      let eventKey = Object.keys(EVENT_PROPERTIES);
      let onlyId = this.getOnlyId(4);
      let json = JSON.parse(temp.json);
      let templateScript = json["templateScript"];

      this.$confirm("是否选择混淆变量、方法、数据源名称（避免与本页面重复，若本页面为空，请选择否）").then(() => {
        let widgetList = this.resetId(json.widgetList, eventKey, onlyId)
        let data = JSON.parse(templateScript.data);
        let funNameList = templateScript.methods.map(i => i.funName);
        let replaceList = [...Object.keys(data), ...funNameList]

        let dataSourceNameList = templateScript.dataSource.map(i => i.name);

        templateScript.methods.forEach(i => {
          i.funName = i.funName + onlyId;
          for (let j = 0; j < replaceList.length; j++) {
            let item = replaceList[j];
            const regex = new RegExp('(?<![A-Za-z0-9_])' + item + '(?![A-Za-z0-9_])', 'g');
            i.funBody = i.funBody.replace(regex, item + onlyId)
            templateScript.data = templateScript.data.replace(regex, item + onlyId)
            templateScript.mounted = templateScript.mounted.replace(regex, item + onlyId)
            templateScript.created = templateScript.created.replace(regex, item + onlyId)
          }
        })

        //处理数据源名称
        let dataSourceObj = ['dataSourceMethods', "dataSourceMapData"];
        templateScript.methods.forEach(i => {
          for (let j = 0; j < dataSourceNameList.length; j++) {
            let item = dataSourceNameList[j];
            for (let k = 0; k < dataSourceObj.length; k++) {
              let m = dataSourceObj[k];
              const regex_1 = new RegExp('this.' + m + '.' + item + '(?![A-Za-z0-9_])', 'g');
              i.funBody = i.funBody.replace(regex_1, `this.${m}.${item + onlyId}`)
                  .replace(`this.${m}['${item}']`, `this.${m}['${item + onlyId}']`)
                  .replace(`this.${m}["${item}"]`, `this.${m}["${item + onlyId}"]`)

              templateScript.mounted = templateScript.mounted.replace(regex_1, `this.${m}.${item + onlyId}`)
                  .replace(`this.${m}['${item}']`, `this.${m}['${item + onlyId}']`)
                  .replace(`this.${m}["${item}"]`, `this.${m}["${item + onlyId}"]`)

              templateScript.created = templateScript.created.replace(regex_1, `this.${m}.${item + onlyId}`)
                  .replace(`this.${m}['${item}']`, `this.${m}['${item + onlyId}']`)
                  .replace(`this.${m}["${item}"]`, `this.${m}["${item + onlyId}"]`)
            }
          }
        })

        templateScript.dataSource.forEach(i => {
          i.name += onlyId;
        })

        this.addToPage(templateScript, widgetList)
      }).catch(() => {
        let widgetList = this.resetId(json.widgetList, [], '')
        this.addToPage(templateScript, widgetList)
      })
    },

    addToPage(templateScript, widgetList) {
      let obj = {};
      if (this.designer.pageScript.data) {
        Object.assign(obj, JSON.parse(this.designer.pageScript.data))
      }
      if (templateScript.data) {
        Object.assign(obj, JSON.parse(templateScript.data))
      }

      let methods = [];
      if (this.designer.pageScript.methods.length > 0) {
        methods.push(...this.designer.pageScript.methods)
      }
      if (templateScript.methods) {
        methods.push(...templateScript.methods)
      }

      let dataSource = [];
      if (this.designer.dataSource.length > 0) {
        dataSource.push(...this.designer.dataSource)
      }
      if (templateScript.dataSource.length > 0) {
        dataSource.push(...templateScript.dataSource)
      }

      this.designer.pageScript.data = JSON.stringify(obj, null, 2)
      this.designer.pageScript.mounted += templateScript.mounted + ";";
      this.designer.pageScript.created += templateScript.created + ";";
      this.designer.pageScript.methods = methods;
      this.designer.dataSource = dataSource;
      widgetList.forEach(i => {
        this.designer.addFieldByDbClick(i);
      })
    },

    resetId(obj, eventKey, onlyId) {
      function reset(obj) {
        // 如果传入的不是对象类型，则直接返回
        if (typeof obj !== 'object' || obj === null) {
          return obj;
        }
        // 定义一个返回的变量
        let copy = {};
        // 判断传入的对象是数组还是对象
        if (obj.constructor === Array) {
          copy = [];
        }
        // 遍历对象的属性
        for (let key in obj) {
          // 判断对象是否有该属性
          if (obj.hasOwnProperty(key)) {
            // 如果该属性是对象类型，则递归调用该函数
            if (typeof obj[key] === 'object' && obj[key] !== null) {
              if (key === "id") {
                // 重置所有组件Id
                copy[key] = obj.type.replace(/-/g, '') + generateId()
              } else if (eventKey.includes(key)) {
                // 对于多组件生成多个命名空间
                copy[key] = obj[key] + onlyId
              } else if (["visible", "dataSource"].includes(key)) {
                copy[key] = obj[key] + onlyId
              } else {
                copy[key] = reset(obj[key]);
              }
            } else {
              // 否则，直接复制属性值
              if (key === "id") {
                copy[key] = obj.type.replace(/-/g, '') + generateId()
              } else if (eventKey.includes(key)) {
                copy[key] = obj[key] + onlyId
              } else if (["visible", "dataSource"].includes(key)) {
                copy[key] = obj[key] + onlyId
              } else {
                copy[key] = obj[key];
              }
            }
          }
        }
        return copy;
      }

      return reset(obj)
    },

    loadFormComponent(data) {
      this.designer.loadFormJson(JSON.parse(data));
    },
    getComponentList() {
      api.componentPage(1, 1000).then((res) => {
        this.componentList = res.data.data.list;
        this.designer.componentList= res.data.data.list;
      });
    },
    changeTab(index) {
      this.active_li = index;
      if (index === 2) {
        this.getComponentList();
      }
    },
    selectedTag(index) {
      this.active_tag = index;
    },
  },
};
</script>

<style scoped lang="scss">
.componentList {
  height: 100%;
  overflow-y: scroll;

  &::-webkit-scrollbar {
    width: 4px;
  }

  ul {
    padding-left: 10px; /* 重置IE11默认样式 */
    margin: 0; /* 重置IE11默认样式 */
    margin-block-start: 0;
    margin-block-end: 0.25em;
    padding-inline-start: 10px;

    &:after {
      content: "";
      display: block;
      clear: both;
    }
  }

  $wh: 60px;

  .field-widget-item {
    display: flex;
    // height: $wh;
    // width: $wh;
    margin: 2px 6px 6px 0;
    cursor: move;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
    background: #fff;
    border: 1px solid #e8e9eb;
    padding: 4px;
    flex-direction: column;
    justify-content: space-between;
    box-sizing: border-box;

    > p {
      margin: 0;
      text-align: center;
    }
  }

  .bottom {
    margin-top: 10px;
    line-height: 12px;
    display: flex;
    align-items: center;
    justify-content: space-between;
  }

  .ft-title {
    font-size: 13px;
    font-weight: bold;
    display: inline-block;
    max-width: 80%;
    overflow: hidden;
  }
}

.component-box {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  // justify-content: space-between;

  > div {
    width: 100%;
  }

  $cbtH: 115px;
  $cbtF: 200px;

  .component-box-top {
    //min-height: $cbtH;
    box-sizing: border-box;

    .cb-top-search {
      width: calc(100% - 20px);
      padding: 10px 10px 10px 5px;
      display: flex;
      flex-direction: row;
      justify-content: space-between;

      ::v-deep .el-input {
        border-radius: 10px;

        .el-input__inner {
          border-radius: 40px;
        }
      }
    }

    .cb-top-filter {
      width: calc(100% - 10px);

      .tabs {
        width: 100%;
        display: flex;
        flex-direction: row;
        flex-wrap: nowrap;
        justify-content: flex-start;
        list-style: none;
        padding: 0;
        background: #f2f2f2;
        //border: 2px solid #f2f2f2;
        border-radius: 4px;
        overflow: hidden;
        margin-top: 0;

        > li {
          padding: 6px 12px;
          font-size: 13px;
          cursor: pointer;
          transition: linear 0.4s;
        }

        .active-li {
          background: $--color-primary;
          color: white;
        }
      }

      .filter {
        > span {
          margin-right: 10px;
          cursor: pointer;
        }
      }
    }
  }
  .bottom-content{
     max-height: calc(100% - #{$cbtH} );
    overflow-y: scroll;
     &::-webkit-scrollbar {
      width: 0;
    }
  }

  .component-box-con {
    // max-height: calc(100% - #{$cbtH} - #{$cbtF} - 30px);
    // overflow-y: scroll;

    &::-webkit-scrollbar {
      width: 0;
    }
  }

  .component-box-foo {
    // min-height: $cbtF;
    // max-height: calc(100% - #{$cbtH} - #{$cbtF});
    // overflow-y: scroll;

    &::-webkit-scrollbar {
      width: 0;
    }
  }

  .el-divider {
    width: calc(100% - 10px);
  }

  .el-divider--horizontal {
    margin: 10px 0 !important;
  }
}
</style>
